package com.newear.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by josan on 2016/07/12.
 * 验证器
 */
public class Validator {

    /**
     * 判断字符串是否有效
     * @return
     */
    public static boolean isEffective(String str) {
        if((str == null) || ("".equals(str)) || (" ").equals(str)
                || ("null").equals(str) || ("\n").equals(str)) {
            return false;
        }
        return true;
    }

    /**
     * 判断数组是否有效
     * @return
     */
    public static boolean isEffective(Object[] obj) {
        if(obj != null && obj.length > 0) {
            return true;
        }
        return false;
    }

    /**
     * 检查UDID是否有效
     * @param id
     * @return
     */
    public static boolean checkUdidValid(String id) {
        if (Validator.isEffective(id) && id.length() >= 10 && !checkUdidZero(id) && !"9774d56d682e549c".equals(id)) { // SDK version 2.2, some devices have the same id
            return true;
        } else
            return false;
    }

    private static boolean checkUdidZero(String id) {
        try {
            int val = Integer.parseInt(id);
            if (val == 0)
                return true;
            else
                return false;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断是否为数字
     * @param str
     * @return
     */
    public static boolean isNumber(String str) {
        if (str == null) {
            return false;
        }
        String regex = "-?[0-9]*$";
        return match(regex, str);
    }

    /**
     * 是不是我们自己的url
     * @return
     */
    public static boolean isOwnerUrl(String url) {
        if (url == null) {
            return false;
        }
        String regex = "(www|api).thatsmags.com";
        return match(regex, url);
    }

    /**
     * 正则表达式判断
     * @param regex
     * @param str
     * @return
     */
    private static boolean match(String regex, String str) {
        if (str == null || regex == null) {
            return false;
        }
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }

    /**
     * 验证邮箱
     *
     * @param str 待验证的字符串
     * @return 如果是符合的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isEmail(String str) {
        String regex = "^([\\w-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([\\w-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
        return match(regex, str);
    }

    /**
     * 验证网址Url
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isUrl(String str) {

        String num = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
        String Ip4 = "(" + num + "\\." + num + "\\." + num + "\\." + num + ")";
        String regex = "(?i)http(?-i)([sS])?[:：]//"
                + "(([0-9A-Za-z]([\\w-]*\\.)+[A-Za-z]+)|" + Ip4+")"
                + "(?::(\\d{1,5}))?(/[\\w- ./?!%&=#:~|]*)?";
        return match(regex, str);
    }

    /**
     * 验证网址Url；校验比较宽松的版本，适合包含Http前缀的字符串判断
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isUrl2(String str) {

        String regex = "(?i)http(?-i)([sS])?[:：]//" + "([\\w-]+\\.)+[\\w-]+"
                + "(?::(\\d{1,5}))?([\\w- ./?!%&=#$_:~|'@;,*+()\\[\\]]*)?";
        return match(regex, str);
    }

    /**
     * 验证电话号码
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isTelephone(String str) {
        String regex = "^(\\+)?(\\d{2,4}-)?(\\d{2,4}-)?\\d{4,13}(-\\d{2,4})?$";
        return match(regex, str);
    }

    /**
     * 验证输入密码条件(字符与数据同时出现)
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isPassword(String str) {
        String regex = "[A-Za-z]+[0-9]";
        return match(regex, str);
    }

    /**
     * 验证输入用户名长度 (3-16位)
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isUsernameLength(String str) {
        String regex = "^\\S{3,16}$";
        return match(regex, str);
    }

    /**
     * 验证输入密码长度 (6-20位)
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isPasswLength(String str) {
        String regex = "^\\S{6,20}$";
        return match(regex, str);
    }

    /**
     * 验证输入邮政编号
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isPostalcode(String str) {
        String regex = "^\\d{6}$";
        return match(regex, str);
    }

    /**
     * 验证输入手机号码
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isMobilePhone(String str) {
        String regex = "^1[3,4,5,7,8]\\d{9}$";
        return match(regex, str);
    }

    /**
     * 验证输入身份证号
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isIDcard(String str) {
        String regex = "(^\\d{18}$)|(^\\d{15}$)";
        return match(regex, str);
    }

    /**
     * 验证输入两位小数
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isDecimal(String str) {
        String regex = "^[0-9]+(.[0-9]{2})?$";
        return match(regex, str);
    }

    /**
     * 验证输入一年的12个月
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isMonth(String str) {
        String regex = "^(0?[[1-9]|1[0-2])$";
        return match(regex, str);
    }

    /**
     * 验证输入一个月的31天
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isDay(String str) {
        String regex = "^((0?[1-9])|((1|2)[0-9])|30|31)$";
        return match(regex, str);
    }

    /**
     * 验证日期时间
     *
     * @param str 待验证的字符串
     * @return 如果是符合网址格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isDate(String str) {
        // 严格验证时间格式的(匹配[2002-01-31], [1997-04-30],
        // [2004-01-01])不匹配([2002-01-32], [2003-02-29], [04-01-01])
        // String regex =
        // "^((((19|20)(([02468][048])|([13579][26]))-02-29))|((20[0-9][0-9])|(19[0-9][0-9]))-((((0[1-9])|(1[0-2]))-((0[1-9])|(1\\d)|(2[0-8])))|((((0[13578])|(1[02]))-31)|(((01,3-9])|(1[0-2]))-(29|30)))))$";
        // 没加时间验证的YYYY-MM-DD
        // String regex =
        // "^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$";
        // 加了时间验证的YYYY-MM-DD 00:00:00
        String regex = "^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\\d):[0-5]?\\d:[0-5]?\\d$";
        return match(regex, str);
    }

    /**
     * 验证非零的正整数
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isIntNumber(String str) {
        String regex = "^\\+?[1-9][0-9]*$";
        return match(regex, str);
    }

    /**
     * 验证大写字母
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isUpChar(String str) {
        String regex = "^[A-Z]+$";
        return match(regex, str);
    }

    /**
     * 验证小写字母
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isLowChar(String str) {
        String regex = "^[a-z]+$";
        return match(regex, str);
    }

    /**
     * 验证验证输入字母
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isAllowedLetter(String str) {
        String regex = "^[0-9A-Za-z\u4e00-\u9fa5\\(\\)_ .&-]+$";
        return match(regex, str);
    }

    /**
     * A-Za-z 大小写字母
     * @param str
     * @return
     */
    public static boolean isLetter(String str) {
        String regex = "^[A-Za-z]+$";
        return match(regex, str);
    }

    /**
     *  0-9A-Za-z 大小写字母数字
     */
    public static boolean isLetterOrNumber(String str) {
        String regex = "^[0-9A-Za-z]";
        return match(regex, str);
    }

    /**
     * 验证输入汉字
     *
     * @param str 待验证的字符串
     * @return 如果是符合格式的字符串,返回 <b>true </b>,否则为 <b>false </b>
     */
    public static boolean isChinese(String str) {
        String regex = "^[\u4e00-\u9fa5]+";
        return match(regex, str);
    }

    /**
     * 经纬度
     * if -90~90 return true; if acceptZero=false, 0.0 return false;
     * @param string double string
     * @param acceptZero
     * @return
     */
    public static boolean isLatitude(String string, boolean acceptZero) {
        try{
            double lat = Double.parseDouble(string);
            if(lat > 90 || lat < -90) return false;
            if(lat == 0 && acceptZero == false) return false;
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 经纬度
     * if -180~180 return true; if acceptZero=false, 0.0 return false;
     * @param string double string
     * @param acceptZero
     * @return
     */
    public static boolean isLongitude(String string, boolean acceptZero) {
        try{
            double lat = Double.parseDouble(string);
            if(lat > 180 || lat < -180) return false;
            if(lat == 0 && acceptZero == false) return false;
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 是否含有json
     * support ..{..{..{..{..}..}..}..}.. four level
     *
     * @param str
     * @return
     */
    public static boolean isContainJson(String str) {
        String base = "(\\{[^\\{\\}]*\\})";
        String wrap1 = "(\\{([^\\{\\}]*" + base + "*[^\\{\\}]*)+\\})";
        String wrap2 = "(\\{([^\\{\\}]*" + wrap1 + "*[^\\{\\}]*)+\\})";
        String wrap3 = "(\\{([^\\{\\}]*" + wrap2 + "*[^\\{\\}]*)+\\})";

        String regex = "[^\\{\\}]*" + wrap3 + "+[^\\{\\}]*$";

        return match(regex, str);
    }

}
